package com.icongyou.enterprise.talent_analysis.mapper;

import com.icongyou.enterprise.talent_analysis.entity.PortraitTemplate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 能力画像模板Mapper测试
 */
@SpringBootTest
@Transactional
public class PortraitTemplateMapperTest {

    @Autowired
    private PortraitTemplateMapper mapper;

    // 使用数据库中存在的用户ID
    private static final String HR_USER_1 = "880e8400-e29b-41d4-a716-446655440401"; // 阿里巴巴 张经理
    private static final String HR_USER_2 = "880e8400-e29b-41d4-a716-446655440402"; // 腾讯 李主管
    private static final String ENTERPRISE_1 = "550e8400-e29b-41d4-a716-446655440003"; // 阿里巴巴
    private static final String ENTERPRISE_2 = "550e8400-e29b-41d4-a716-446655440004"; // 腾讯
    private static final String ENTERPRISE_3 = "550e8400-e29b-41d4-a716-446655440005"; // 华为

    @BeforeEach
    public void setUp() {
        // 清理测试数据，确保测试独立性
        // 注意: @Transactional会自动回滚，但这里提供额外保护
    }

    @Test
    public void testInsertAndSelectById() {
        PortraitTemplate template = createTemplate(
            UUID.randomUUID().toString(), 
            ENTERPRISE_1, 
            "技术岗位模板"
        );
        
        int result = mapper.insert(template);
        assertEquals(1, result);

        PortraitTemplate retrieved = mapper.selectById(template.getId());
        assertNotNull(retrieved);
        assertEquals(template.getId(), retrieved.getId());
        assertEquals(ENTERPRISE_1, retrieved.getEnterpriseId());
        assertEquals("技术岗位模板", retrieved.getTemplateName());
        assertTrue(retrieved.getActive());
    }

    @Test
    public void testSelectById_notFound() {
        PortraitTemplate retrieved = mapper.selectById("nonexistent-id");
        assertNull(retrieved);
    }

    @Test
    public void testUpdateById() {
        PortraitTemplate template = createTemplate(
            UUID.randomUUID().toString(), 
            ENTERPRISE_1, 
            "原始名称"
        );
        mapper.insert(template);

        // 更新
        template.setTemplateName("更新后的名称");
        template.setDescription("更新后的描述");
        template.setDimensionsJson("{\"updated\":true}");
        template.setActive(false);
        template.setUpdatedAt(LocalDateTime.now());

        int result = mapper.updateById(template);
        assertEquals(1, result);

        PortraitTemplate updated = mapper.selectById(template.getId());
        assertNotNull(updated);
        assertEquals("更新后的名称", updated.getTemplateName());
        assertEquals("更新后的描述", updated.getDescription());
        assertFalse(updated.getActive());
    }

    @Test
    public void testSelectByEnterprise_all() {
        String enterpriseId = ENTERPRISE_2;
        
        // 插入多个模板
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "模板1", true));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "模板2", false));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "模板3", true));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), ENTERPRISE_1, "其他企业模板", true));

        List<PortraitTemplate> templates = mapper.selectByEnterprise(enterpriseId, null);
        
        assertNotNull(templates);
        assertEquals(3, templates.size()); // 只返回该企业的模板
    }

    @Test
    public void testSelectByEnterprise_activeOnly() {
        String enterpriseId = ENTERPRISE_2; // 使用腾讯,没有预置数据
        
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "激活模板1", true));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "激活模板2", true));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "未激活模板", false));

        List<PortraitTemplate> templates = mapper.selectByEnterprise(enterpriseId, true);
        
        assertNotNull(templates);
        assertEquals(2, templates.size()); // 只返回激活的模板
        assertTrue(templates.stream().allMatch(PortraitTemplate::getActive));
    }

    @Test
    public void testSelectByEnterprise_inactiveOnly() {
        String enterpriseId = ENTERPRISE_2;
        
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "激活模板", true));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "未激活模板1", false));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "未激活模板2", false));

        List<PortraitTemplate> templates = mapper.selectByEnterprise(enterpriseId, false);
        
        assertNotNull(templates);
        assertEquals(2, templates.size());
        assertTrue(templates.stream().noneMatch(PortraitTemplate::getActive));
    }

    @Test
    public void testSelectByEnterprise_empty() {
        List<PortraitTemplate> templates = mapper.selectByEnterprise("nonexistent-enterprise", null);
        
        assertNotNull(templates);
        assertTrue(templates.isEmpty());
    }

    @Test
    public void testCountByCreatedBy() {
        String createdBy = HR_USER_2; // 使用腾讯HR,没有预置数据
        
        // 插入多个该用户创建的模板
        for (int i = 0; i < 3; i++) {
            PortraitTemplate template = createTemplate(
                UUID.randomUUID().toString(), 
                ENTERPRISE_2, 
                "模板" + i
            );
            template.setCreatedBy(createdBy);
            mapper.insert(template);
        }

        // 插入其他用户创建的模板
        PortraitTemplate other = createTemplate(
            UUID.randomUUID().toString(), 
            ENTERPRISE_2, 
            "其他模板"
        );
        other.setCreatedBy(HR_USER_1);
        mapper.insert(other);

        int count = mapper.countByCreatedBy(createdBy);
        assertEquals(3, count);
    }

    @Test
    public void testCountByCreatedBy_zero() {
        int count = mapper.countByCreatedBy("nonexistent-user");
        assertEquals(0, count);
    }

    @Test
    public void testClearActiveFlag() {
        String enterpriseId = ENTERPRISE_3;
        
        // 先清理该企业的现有数据，确保测试独立性
        mapper.clearActiveFlag(enterpriseId);
        List<PortraitTemplate> existingTemplates = mapper.selectByEnterprise(enterpriseId, null);
        for (PortraitTemplate template : existingTemplates) {
            mapper.deleteById(template.getId());
        }
        
        // 插入多个激活的模板
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "模板1", true));
        mapper.insert(createTemplate(UUID.randomUUID().toString(), enterpriseId, "模板2", true));
        String template3Id = UUID.randomUUID().toString();
        mapper.insert(createTemplate(template3Id, enterpriseId, "模板3", true));
        
        // 插入其他企业的模板
        String otherTemplateId = UUID.randomUUID().toString();
        mapper.insert(createTemplate(otherTemplateId, ENTERPRISE_1, "其他企业", true));

        int result = mapper.clearActiveFlag(enterpriseId);
        assertEquals(3, result);

        // 验证该企业的模板都被禁用
        List<PortraitTemplate> templates = mapper.selectByEnterprise(enterpriseId, true);
        assertTrue(templates.isEmpty());

        // 验证其他企业的模板不受影响
        PortraitTemplate other = mapper.selectById(otherTemplateId);
        assertTrue(other.getActive());
    }

    @Test
    public void testDeleteById() {
        String templateId = UUID.randomUUID().toString();
        PortraitTemplate template = createTemplate(templateId, ENTERPRISE_1, "待删除模板");
        mapper.insert(template);

        int result = mapper.deleteById(templateId);
        assertEquals(1, result);

        PortraitTemplate retrieved = mapper.selectById(templateId);
        assertNull(retrieved);
    }

    @Test
    public void testDeleteById_notExists() {
        int result = mapper.deleteById("nonexistent-template");
        assertEquals(0, result);
    }

    @Test
    public void testInsert_withAiSuggested() {
        String templateId = UUID.randomUUID().toString();
        PortraitTemplate template = createTemplate(templateId, ENTERPRISE_1, "AI推荐模板");
        template.setAiSuggested(true);
        
        mapper.insert(template);

        PortraitTemplate retrieved = mapper.selectById(templateId);
        assertNotNull(retrieved);
        assertTrue(retrieved.getAiSuggested());
    }

    @Test
    public void testInsert_withComplexDimensionsJson() {
        String templateId = UUID.randomUUID().toString();
        PortraitTemplate template = createTemplate(templateId, ENTERPRISE_1, "复杂模板");
        String complexJson = "[{\"code\":\"tech\",\"name\":\"技术能力\",\"weight\":0.3}," +
                            "{\"code\":\"team\",\"name\":\"团队协作\",\"weight\":0.7}]";
        template.setDimensionsJson(complexJson);
        
        mapper.insert(template);

        PortraitTemplate retrieved = mapper.selectById(templateId);
        assertNotNull(retrieved);
        // 比较时忽略JSON格式化空格差异
        String retrievedJson = retrieved.getDimensionsJson().replaceAll("\\s+", "");
        String expectedJson = complexJson.replaceAll("\\s+", "");
        assertEquals(expectedJson, retrievedJson);
    }

    // ==================== Helper Methods ====================

    private PortraitTemplate createTemplate(String id, String enterpriseId, String templateName) {
        return createTemplate(id, enterpriseId, templateName, true);
    }

    private PortraitTemplate createTemplate(String id, String enterpriseId, String templateName, boolean active) {
        PortraitTemplate template = new PortraitTemplate();
        template.setId(id);
        template.setEnterpriseId(enterpriseId);
        template.setTemplateName(templateName);
        template.setDescription("描述：" + templateName);
        template.setDimensionsJson("{\"dimensions\":[]}");
        template.setActive(active);
        template.setAiSuggested(false);
        template.setCreatedBy(HR_USER_1); // 使用真实存在的用户ID
        template.setCreatedAt(LocalDateTime.now());
        template.setUpdatedAt(LocalDateTime.now());
        return template;
    }
}
